import csv
from enum import Enum
from typing import List
from typing import NamedTuple

from color import str_bgcolor
from color import str_color


try:
    with open("anonymized.csv", encoding="utf-8") as file:
        _anonymized = dict(csv.reader(file))
except IOError:
    _anonymized = {}


def _brackets(s: str) -> str:
    return f"[{s}]"


def anonymize_text(s: str) -> str:
    for name, anon in _anonymized.items():
        s = s.replace(_brackets(name), _brackets(anon)).replace(name, "{" + anon + "}")
    return s


def anonymize_name(name: str) -> str:
    return Person.lookup_or_create(name).name


class Gender(Enum):
    Female = 0
    Male = 1


class Person(NamedTuple):
    id: int
    actual_name: str
    aliases: List[str] = []

    people = {}
    _last_id = 0

    @classmethod
    def lookup_or_create(cls, name: str):
        try:
            return cls.people[name]
        except KeyError:
            cls._last_id += 1
            person = cls(
                id=cls._last_id,
                actual_name=name,
            )
            cls.people[id] = person
            cls.people[name] = person
            return person

    @property
    def anonymized(self) -> str:
        return self.actual_name in _anonymized

    @property
    def name(self) -> str:
        if self.anonymized:
            return _brackets(_anonymized[self.actual_name])
        return self.actual_name

    @property
    def color(self) -> str:
        return str_color(self.name)

    @property
    def bgcolor(self) -> str:
        return str_bgcolor(self.name)

    @property
    def gender(self) -> bool:
        # For now, just a heuristic based on Czech surname rules
        try:
            if self.actual_name.split()[0][-1] == "á":
                return Gender.Female
            else:
                return Gender.Male
        except IndexError:
            return Gender.Male
